<template>
  <div class="calendar" v-if="calendarInit">
    <slot name="header" v-if="needHeader">
      <div class="calendar__header">
        <div class="header__pre" @click="handlePreMonth"></div>
        <div class="header__title">{{ selectedYear }}年{{ selectedMonth + 1 }}月{{ selectedDate }}日</div>
        <div class="header__next" @click="handleNextMonth"></div>
      </div>
    </slot>
    <!-- 月展示 -->
    <div class="calendar__main" v-show="monthWeek">
      <div
        class="main__block-head"
        :style="{ height: blockHeight }"
        v-for="(item, index) in calendarHeader"
        :key="index">
        {{ item }}
      </div>

      <div
        :style="{ height: blockHeight }"
        class="show_info"
        :class="`main__block main__block-${calendarID} ${
          item.type === 'pre' || item.type === 'next' ? 'main__block-not' : ''
        } ${item.content === selectedDate && item.type === 'normal' ? 'main__block-today' : ''} ${
          item.type != 'normal' ? 'reset' : ''
        }`"
        @click="handleDayClick(item, index)"
        v-for="(item, index) in calendarData[selectedMonth]"
        :key="item.type + item.content + `${index}`">
        <span class="time">{{ item.content }}</span>
        <span v-if="pageTypes == '1' && item.meetingInfo && item.meetingInfo.length" class="tip">●</span>
      </div>
    </div>
    <!-- 周展示 -->
    <div class="calendar__main" v-show="!monthWeek">
      <div
        class="main__block-head"
        :style="{ height: blockHeight }"
        v-for="(item, index) in calendarHeader"
        :key="index">
        {{ item }}
      </div>

      <div
        :style="{ height: blockHeight }"
        class="show_info"
        :class="`main__block main__block-${calendarID} ${
          item.type === 'pre' || item.type === 'next' ? 'main__block-not' : ''
        } ${item.content === selectedDate && item.type === 'normal' ? 'main__block-today' : ''} ${
          item.type != 'normal' ? 'reset' : ''
        }`"
        @click="handleDayClick(item, index)"
        v-for="(item, index) in weekData"
        :key="item.type + item.content + `${index}`">
        <span class="time">{{ item.content }}</span>
        <span v-if="pageTypes == '1' && item.meetingInfo && item.meetingInfo.length" class="tip">●</span>
      </div>
    </div>
    <!-- 周月切换 -->
    <div class="week_month">
      <div class="left"></div>
      <div class="center" @click="monthWeek = !monthWeek">
        <van-icon v-show="monthWeek" name="arrow-up" />
        <van-icon v-show="!monthWeek" name="arrow-down" />
      </div>
      <div class="right"></div>
    </div>
  </div>
</template>

<script>
/* eslint-disable */
import dayjs from 'dayjs'
import moment from 'moment'
export default {
  name: 'calendar',
  components: {},
  props: {
    needHeader: {
      type: Boolean,
      default: false,
    },
    outerCalendarData: {
      type: Array,
      default: function () {
        return []
      },
    },
    pageTypes: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      calendarID: Date.now(),
      calendarInit: false,
      calendarShow: false,
      calendarHeader: ['一', '二', '三', '四', '五', '六', '日'],
      calendarData: [],
      blockHeight: '',
      selectedYear: 2013,
      selectedMonth: 9,
      selectedDate: 30,
      weekData: [],
      monthWeek: true,
      today: false,
    }
  },
  computed: {
    isFirstMonth() {
      return this.selectedMonth === 0
    },
    isLastMonth() {
      return this.selectedMonth === 11
    },
  },
  watch: {},
  created() {},
  mounted() {
    this.init()
    // this.$nextTick(() => {
    //   this.blockHeight = document.querySelector(`.main__block-${this.calendarID}`).offsetWidth - 0 + 'px'
    //   this.monthWeek = this.weekMonth
    // })
  },
  methods: {
    init() {
      const initDate = dayjs(Date.now()).format('YYYY/MM/DD')
      const [year, month, date] = initDate.split('/')
      this.selectedYear = Number(year)
      this.selectedMonth = Number(month) - 1
      this.selectedDate = Number(date)
      this.calendarData = this.getAllDaysForYear(Number(year))
      this.getNowWeekData('one', dayjs().day(), 'normal')
      this.$emit('fetchCalendar', { calendar: this.calendarData })
      this.calendarInit = true
    },

    handleDayClick(item, index) {
      if (item.type === 'normal') {
        this.selectedDate = Number(item.content)
        this.$emit('selectDate', item)
        if (this.monthWeek) {
          this.getNowWeekData('noone', index, item.type)
        }
      }
    },

    handlePreMonth(item) {
      if (this.isFirstMonth) {
        this.selectedYear = this.selectedYear - 1
        this.calendarData = this.getAllDaysForYear(Number(this.selectedYear))
      }
      this.selectedDate = Number(item.content)
      this.selectedMonth = this.isFirstMonth ? 11 : this.selectedMonth - 1
      this.$emit('preMonth', { month: this.selectedMonth })
    },

    handleNextMonth(item) {
      if (this.isLastMonth) {
        this.selectedYear = this.selectedYear + 1
        this.calendarData = this.getAllDaysForYear(Number(this.selectedYear))
      }
      this.selectedDate = Number(item.content)
      this.selectedMonth = this.isLastMonth ? 0 : this.selectedMonth + 1
      this.$emit('nextMonth', { month: this.selectedMonth })
    },
    getAllDaysForYear(year) {
      /**
       * monthData 每月数据 用于最后输出
       * daysInMonth 每个月的天数
       * specialDaysInMonth 每个月第一天和最后一天的星期
       */
      const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

      // 对闰年二月天数特殊处理
      if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
        daysInMonth[1] = 29
      }
      const monthData = new Array(12).fill(null)
      const specialDaysInMonth = monthData.slice(0).map((m, i) => {
        return [new Date(year, i, 1).getDay(), new Date(year, i, daysInMonth[i]).getDay()]
      })

      return monthData.map((m, i) => {
        const month = []
        const pre = this.preDaysCreator(daysInMonth[i === 0 ? 11 : i - 1], specialDaysInMonth[i][0])
        const normal = this.normalDaysCreator(daysInMonth[i])
        const next = this.nextDaysCreator(specialDaysInMonth[i][1])
        return month.concat(pre, normal, next)
      })
    },
    preDaysCreator(preLastDay, firstDay) {
      if (firstDay === 0) {
        firstDay = 7
      }
      let sub = preLastDay - firstDay + 2
      const preDays = []
      for (; firstDay - 1 > 0; firstDay--) {
        let obj = {
          content: sub++,
          type: 'pre',
        }

        preDays.push(obj)
      }
      return preDays
    },
    nextDaysCreator(lastDay) {
      if (lastDay === 0) {
        lastDay = 7
      }
      const nextDays = []
      // const count = 6 - lastDay // 周日为第一个
      const count = 7 - lastDay // 周一为第一个
      for (let i = 0; i < count; i++) {
        let obj = {
          content: i + 1,
          type: 'next',
        }

        nextDays.push(obj)
      }
      return nextDays
    },
    normalDaysCreator(days) {
      const normalDays = []
      for (let i = 0; i < days; i++) {
        let obj = {
          content: i + 1,
          type: 'normal',
        }

        normalDays.push(obj)
      }
      return normalDays
    },
    getNowWeekData(form, week, type) {
      let arrData = []
      if (form === 'noone') {
        let i = 0
        if ((week + 1) % 7 == 0) {
          i = ((week + 1 - ((week + 1) % 7)) / 7) * 7 - 1
        } else {
          i = ((week + 1 - ((week + 1) % 7)) / 7 + 1) * 7 - 1
        }
        for (let t = i - 6; t <= i; t++) {
          arrData.push(this.calendarData[this.selectedMonth][t])
        }
      } else {
        // 针对月数组做循环
        for (let t = 0; t < this.calendarData[this.selectedMonth].length; t += 7) {
          if (
            week + t - 1 >= 0 &&
            this.calendarData[this.selectedMonth][week + t - 1].content &&
            this.calendarData[this.selectedMonth][week + t - 1].content === this.selectedDate
          ) {
            let i = (t / 7 + 1) * 7 - 1
            for (let t1 = i - 6; t1 <= i; t1++) {
              arrData.push(this.calendarData[this.selectedMonth][t1])
            }
            break
          }
        }
      }
      this.weekData = arrData
    },
    // 获取高度
    getHeight() {
      this.$nextTick(() => {
        this.blockHeight = this.blockHeight
          ? this.blockHeight
          : document.querySelector(`.main__block-${this.calendarID}`).offsetWidth - 0 + 'px'
        if (this.pageTypes == '1') {
          this.monthWeek = true
        } else {
          this.monthWeek = false
        }
      })
    },
    // 日历状态梳理
    calendarShowData(data) {
      let arr = data.time.split('-')
      this.selectedYear = Number(arr[0])
      this.selectedMonth = Number(arr[1]) - 1
      this.calendarData = this.getAllDaysForYear(this.selectedYear)
      let preArr = this.calendarData[this.selectedMonth].filter(item => {
        return item.type === 'pre'
      })
      let nowArr = this.calendarData[this.selectedMonth].filter(item => {
        return item.type === 'normal'
      })
      let nextArr = this.calendarData[this.selectedMonth].filter(item => {
        return item.type === 'next'
      })
      let nowNew = []
      for (let i = 0; i < nowArr.length; i++) {
        let timeOne = { timeOne: moment(`${this.selectedYear}-${arr[1]}-${nowArr[i].content}`).format('YYYY-MM-DD') }
        let dataOne = Object.assign(nowArr[i], data.info[i], timeOne)
        nowNew.push(dataOne)
      }
      if (this.selectedMonth === new Date().getMonth()) {
        this.selectedDate = Number(new Date().getDate())
        this.getNowWeekData('one', dayjs().day(), 'normal')
      } else {
        this.selectedDate = 1
        this.getNowWeekData('noone', preArr.length, 'normal')
      }
      this.calendarData[this.selectedMonth] = preArr.concat(nowNew, nextArr)
      // console.log('nowNew :>> ', nowNew)
      for (let i in this.calendarData[this.selectedMonth]) {
        if (
          this.calendarData[this.selectedMonth][i].type === 'normal' &&
          this.calendarData[this.selectedMonth][i].content === this.selectedDate
        ) {
          this.$emit('selectDate', this.calendarData[this.selectedMonth][i])
          break
        }
      }
    },
    // 未来日期不显示点
    tipShow(content) {
      if (new Date(this.selectedYear, this.selectedMonth, content).getTime() > new Date().getTime()) {
        return false
      } else {
        return true
      }
    },
    changeWeek() {
      this.monthWeek = false
    },
  },
}
</script>

<style lang="scss">
.calendar {
  flex-shrink: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  border-radius: 4px;
  background-color: white;
}

.calendar__header {
  color: #2c3135;
  font-size: 16px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  line-height: 22px;
  margin: 17px 0;
}

.header__title {
  font-size: 16px;
  letter-spacing: 1px;
}

.header__pre {
  height: 12px;
  width: 12px;
  position: relative;

  &:after {
    content: ' ';
    display: inline-block;
    height: 9px;
    width: 9px;
    border-width: 2px 2px 0 0;
    border-color: #c8c8cd;
    border-style: solid;
    transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0) rotate(180deg);
    position: absolute;
    top: 50%;
    margin-top: -4px;
    left: 10px;
  }
}

.header__next {
  height: 12px;
  width: 12px;
  position: relative;

  &:after {
    content: ' ';
    display: inline-block;
    height: 9px;
    width: 9px;
    border-width: 2px 2px 0 0;
    border-color: #c8c8cd;
    border-style: solid;
    transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
    position: absolute;
    top: 50%;
    margin-top: -4px;
    left: -10px;
  }
}

.calendar__main {
  width: 100%;
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
}

.main__block {
  width: calc(100% / 7);
  margin-bottom: 15px;
  border-radius: 2px;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #333333;
  background-color: #fff;
  flex-shrink: 0;
  box-shadow: 0;
  position: relative;
}

.main__block-piont {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: #a97e4c;
  position: absolute;
  left: calc(50% - 2.5px);
  bottom: 0;
}

.main__block-not {
  // background-color: #edf2f5;
  color: #b9b9b9;
}

.main__block-today {
  transition: 0.5s all;
  // background-color: #a97e4c;
  background-color: #b6c2ce;
  color: #fff;
  box-shadow: 0 2px 6px rgba(171, 171, 171, 0.5);
  border-radius: 50%;
}

.main__block-head {
  width: calc(100% / 7);
  margin-bottom: 15px;
  border-radius: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: #666666;
  background-color: #fff;
  flex-shrink: 0;
}
.reset {
  color: #b9b9b9;
}
.show_info {
  display: flex;
  flex-direction: column;
  font-size: 12px;
  position: relative;
  .tip {
    font-size: 12px;
    // color: #cccc13;
    color: #d6494a;
    // color: #8faece;
    position: absolute;
    top: 5px;
    // bottom: -9px;
  }
  .tip_now {
    opacity: 0;
  }
}
.week_month {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0 15px;
  .left,
  .right {
    height: 1px;
    background-color: #f5f5f5;
    width: 130px;
  }
  .center {
    color: #999999;
    font-size: 12px;
  }
}
</style>
